﻿using IService;
using Microsoft.AspNetCore.Mvc;
using Model;
using Newtonsoft.Json;

namespace WMS.Controllers
{
    public class WhInboundController : Controller
    {
        private readonly IDictService _dictService;
        private readonly IWhInboundService _whInboundService;
        private readonly IWebHostEnvironment _webHostEnv; // 新增：用于获取服务器路径

        public WhInboundController(
            IDictService dictService, 
            IWhInboundService whInboundService,
            IWebHostEnvironment webHostEnv)
        {
            _dictService = dictService;
            _whInboundService = whInboundService;
            _webHostEnv = webHostEnv;
        }

        public async Task<IActionResult> Index()
        {
            var dictTypeForStockIn = await _dictService.GetDictTypeAsync("sys_stockin_type");
            if (dictTypeForStockIn != null)
            {
                var stockInTypeList = await _dictService.GetDictDataListAsync(dictTypeForStockIn.DictTypeId);
                ViewBag.StockInTypeList = stockInTypeList;
            }
            var dictTypeForOrderStatu = await _dictService.GetDictTypeAsync("sys_order_statu");
            if (dictTypeForOrderStatu != null)
            {
                var orderStatusList = await _dictService.GetDictDataListAsync(dictTypeForOrderStatu.DictTypeId);
                ViewBag.OrderStatusList = orderStatusList;
            }
            
            return View();
        }

        /// <summary>
        /// 获取入库单信息
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> GetAllInfo()
        {
            var result = await _whInboundService.GetAllInboundInfo();
            return Json(result);
        }

        /// <summary>
        /// 获取仓库信息用于选择
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> GetWareHouseInfoForSelect()
        {
            var result = await _whInboundService.GetWareHouseInfoForSelect();
            return Json(result);
        }

        /// <summary>
        /// 多条件查询入库单
        /// </summary>
        /// <param name="wisws"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> GetSomeWhInboundInfo([FromBody] WhInbSelectWithSth wisws)
        {
            var result = await _whInboundService.GetSomeInboundInfo(wisws);
            return Json(result);
        }

        /// <summary>
        /// 批量删除入库单
        /// </summary>
        /// <param name="dwir"></param>
        /// <returns></returns>
        public class DeleteWhInbRequest
        {
            public List<long> OrderIdList { get; set; }
            public long UserId { get; set; }
        }
        [HttpPost]
        public async Task<IActionResult> DeleteWhInbound([FromBody] DeleteWhInbRequest dwir)
        {
            var result = await _whInboundService.DeleteWhInbound(dwir.OrderIdList,dwir.UserId);
            return Json(result);
        }

        

        /// <summary>
        /// 可批量撤销入库单
        /// </summary>
        /// <param name="cwisr"></param>
        /// <returns></returns>
        public class ChangeWhInbStatuRequest
        {
            public List<long> WhOrderIdList { get; set; }
            public string NewStatu { get; set; }
            public long UserId { get; set; }
        }
        public async Task<IActionResult> ChangeWhInboundStatu([FromBody] ChangeWhInbStatuRequest cwisr)
        {
            var result = await _whInboundService.ChangeWhInboundStatu(cwisr.WhOrderIdList, cwisr.NewStatu, cwisr.UserId);
            return Json(result);
        }


        /// <summary>
        /// 批量审核/驳回入库单
        /// </summary>
        /// <param name="awir"></param>
        /// <returns></returns>
        public class AuditeWhInbRequest
        {
            public List<long> WhOrderIdList { get; set; }
        public string OrderStatu { get; set; }
        public long AuditorId { get; set; }
        public string AuditorComment { get; set; }
        }
        public async Task<IActionResult> AuditeWhInboundOrder([FromBody] AuditeWhInbRequest awir)
        {
            var result = await _whInboundService.AuditeWhInboundOrder(awir.WhOrderIdList, awir.OrderStatu, awir.AuditorId, awir.AuditorComment);
            return Json(result);
        }

        /// <summary>
        /// 添加页面
        /// </summary>
        /// <returns></returns>
        public async Task<IActionResult> AddIndex()
        {
            var dictTypeForStockIn = await _dictService.GetDictTypeAsync("sys_stockin_type");
            if (dictTypeForStockIn != null)
            {
                var stockInTypeList = await _dictService.GetDictDataListAsync(dictTypeForStockIn.DictTypeId);
                ViewBag.StockInTypeList = stockInTypeList;
            }
            var dictTypeForStockinOrderStatu = await _dictService.GetDictTypeAsync("sys_stockin_order_statu");
            if (dictTypeForStockinOrderStatu != null)
            {
                var stockInStatusList = await _dictService.GetDictDataListAsync(dictTypeForStockinOrderStatu.DictTypeId);
                ViewBag.StockInOrderStatusList = stockInStatusList;
            }
            return View();
        }

        /// <summary>
        /// 关联单号选择
        /// </summary>
        /// <returns></returns>
        public async Task<IActionResult> OmPurchaseOrderDetailForSelect()
        {
            var result = await _whInboundService.OmPurchaseOrderSourceDetailsForSelect();
            return Json(result);
        }

        /// <summary>
        /// 多条件查询关联进货单号详细信息
        /// </summary>
        /// <param name="wisws"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> OmPurOrderSelectWithSth([FromBody] WhInSelectWithSth wisws)
        {
            var result = await _whInboundService.GetOmPurchaseOrderSourceWithSth(wisws);
            return Json(result);
        }

        /// <summary>
        /// 根据进货单号查询进货单商品详情
        /// </summary>
        /// <param name="upOrderId"></param>
        /// <returns></returns>
        public async Task<IActionResult> GetOmPurOrderGoodsDetail(long upOrderId)
        {
            var result = await _whInboundService.GetOmPurOrderGoodsDetail(upOrderId);
            return Json(result);
        }

        /// <summary>
        /// 根据仓库ID选择仓位信息用于入库单
        /// </summary>
        /// <param name="warehouseId"></param>
        /// <returns></returns>
        public async Task<IActionResult> SelectWhLocationForInbound(long warehouseId)
        {
            var result = await _whInboundService.SelectWhLocationForInbound(warehouseId);
            return Json(result);
        }


        /// <summary>
        /// 附件上传（选择文件时调用）
        /// </summary>
        /// <param name="file">前端上传的单个文件</param>
        /// <returns>文件唯一标识、名称、大小等信息</returns>
        [HttpPost]
        public async Task<IActionResult> UploadAttachment(IFormFile file)
        {
            // 1. 校验文件合法性（格式、大小）
            if (file == null || file.Length == 0)
            {
                return Json(new { success = false, message = "请选择有效的文件" });
            }

            var allowedExtensions = new[] { ".doc", ".docx", ".pdf", ".rar", ".zip" };
            var fileExtension = Path.GetExtension(file.FileName).ToLower();
            if (!allowedExtensions.Contains(fileExtension))
            {
                return Json(new { success = false, message = "仅支持 doc、docx、pdf、rar、zip 格式" });
            }

            // 单个文件最大200MB（与前端提示一致）
            var maxFileSize = 200 * 1024 * 1024; // 200MB
            if (file.Length > maxFileSize)
            {
                return Json(new { success = false, message = "单个文件大小不能超过200MB" });
            }

            // 2. 定义服务器保存路径（建议放在 wwwroot 下，方便管理）
            var uploadDir = Path.Combine(_webHostEnv.WebRootPath, "uploads", "wh-inbound");
            // 若目录不存在，自动创建
            if (!Directory.Exists(uploadDir))
            {
                Directory.CreateDirectory(uploadDir);
            }

            // 3. 生成唯一文件名（避免重复覆盖，用 GUID 命名）
            var uniqueFileName = $"{Guid.NewGuid()}{fileExtension}"; // 例：550e8400-e29b-41d4-a716-446655440000.pdf
            var savePath = Path.Combine(uploadDir, uniqueFileName);

            // 4. 保存文件到服务器
            using (var stream = new FileStream(savePath, FileMode.Create))
            {
                await file.CopyToAsync(stream);
            }

            // 5. 生成文件唯一标识（fileId，建议用 GUID 或数据库自增ID，此处用文件名简化）
            var fileId = uniqueFileName; // 实际项目可存入数据库生成自增ID，此处暂用唯一文件名作为标识

            // 6. 返回结果给前端（前端需存储 fileId，用于后续删除）
            return Json(new
            {
                success = true,
                data = new
                {
                    fileId = fileId,          // 唯一标识，删除时需传此值
                    fileName = file.FileName, // 原始文件名（用于前端显示）
                    fileSize = file.Length,   // 文件大小（字节）
                    savePath = savePath       // 服务器保存路径（可选，用于后续关联入库单）
                },
                message = "文件上传成功"
            });
        }

        /// <summary>
        /// 附件删除（点击移除时调用）
        /// </summary>
        /// <param name="fileId">上传时返回的文件唯一标识</param>
        /// <returns>删除结果</returns>
        [HttpPost]
        public IActionResult DeleteAttachment([FromBody] DeleteAttachmentRequest request)
        {
            // 1. 校验 fileId
            if (string.IsNullOrEmpty(request.FileId))
            {
                return Json(new { success = false, message = "文件标识不能为空" });
            }

            // 2. 拼接服务器文件路径（与上传时的路径一致）
            var uploadDir = Path.Combine(_webHostEnv.WebRootPath, "uploads", "wh-inbound");
            var filePath = Path.Combine(uploadDir, request.FileId);

            // 3. 检查文件是否存在，存在则删除
            if (System.IO.File.Exists(filePath))
            {
                try
                {
                    System.IO.File.Delete(filePath);
                }
                catch (Exception ex)
                {
                    return Json(new { success = false, message = $"文件删除失败：{ex.Message}" });
                }
            }
            else
            {
                return Json(new { success = false, message = "文件不存在，无需删除" });
            }

            // 4. （可选）删除数据库中该文件的临时关联信息（如暂存的 fileId 与入库单草稿的关联）
            // 此处需调用 Service 层方法，删除临时表中的记录，示例：
            // await _whInboundService.DeleteTempAttachment(request.FileId);

            // 5. 返回删除结果
            return Json(new { success = true, message = "文件删除成功" });
        }

        /// <summary>
        /// 新增入库单、入库明细和附件
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult AddWhInbound([FromBody] AddWhInboundRequest request)
        {
            // 1. 基础参数校验
            if (request == null || request.InboundMain == null)
                return Json(new { success = false, message = "入库单主信息不能为空" });
            if (request.InboundDetails == null || request.InboundDetails.Count == 0)
                return Json(new { success = false, message = "请添加至少一条进货明细" });

            try
            {
                // 2. 调用 Service 层保存
                var result = _whInboundService.AddWhInbound(
                    request.InboundMain,
                    request.InboundDetails,
                    request.Attachments
                );

                // 3. 判断是否成功，失败则回滚附件
                if (result > 0)
                {
                    return Json(new { success = true, message = "入库单保存成功" });
                }
                else
                {
                    // 保存失败，删除已上传的附件
                    RollbackAttachments(request.AttachmentFileIds);
                    return Json(new { success = false, message = "入库单保存失败，请重试" });
                }
            }
            catch (Exception ex)
            {
                // 异常时回滚附件
                RollbackAttachments(request.AttachmentFileIds);

                // 记录日志
                Console.WriteLine($"保存入库单异常：{ex.Message}");
                return Json(new { success = false, message = $"服务器异常：{ex.Message}" });
            }
        }

        //添加入库单实体
        public class AddWhInboundRequest
        {
            public WhInboundForAdd InboundMain { get; set; }
            public List<WhInboundDetailForAdd> InboundDetails { get; set; }
            public List<SysAttachmentDTO>? Attachments { get; set; }
            public List<string>? AttachmentFileIds { get; set; }
        }



        //辅助方法------------------------------------------------------------------------------------------

        // 新增：删除附件的请求参数类（接收前端传递的 fileId）
        public class DeleteAttachmentRequest
        {
            public string FileId { get; set; }
        }

        /// <summary>
        /// 封装：根据 fileId 删除服务器上的附件
        /// </summary>
        /// <param name="fileId">附件唯一标识</param>
        /// <returns>是否删除成功</returns>
        private bool DeleteAttachmentByFileId(string fileId)
        {
            var uploadDir = Path.Combine(_webHostEnv.WebRootPath, "uploads", "wh-inbound");
            var filePath = Path.Combine(uploadDir, fileId);

            if (System.IO.File.Exists(filePath))
            {
                try
                {
                    System.IO.File.Delete(filePath);
                    return true;
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"删除附件失败：{ex.Message}");
                    return false;
                }
            }
            return true; // 文件不存在时，视为“已删除”
        }

        /// <summary>
        /// 回滚：删除已上传的附件
        /// </summary>
        /// <param name="attachmentFileIds">已上传的附件 ID 列表</param>
        private void RollbackAttachments(List<string>? attachmentFileIds)
        {
            if (attachmentFileIds == null || !attachmentFileIds.Any()) return;

            foreach (var fileId in attachmentFileIds)
            {
                DeleteAttachmentByFileId(fileId);
            }
        }
    }
}
